package com.sinopec.yelofixedreader.stock.inn.view

import android.os.Bundle
import android.util.Log
import android.view.Gravity
import android.view.KeyEvent
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.sinopec.basemodule.BaseApplication
import com.sinopec.basemodule.adapter.AlreadyReadAreaAdapter
import com.sinopec.basemodule.adapter.ReadCodeAreaAdapter
import com.sinopec.basemodule.base.CustomToolbar
import com.sinopec.basemodule.base.basekt.BaseActivityKt
import com.sinopec.basemodule.dialog.CommonTipsPopupWindow
import com.sinopec.basemodule.dialog.TipsPopupWindow
import com.sinopec.basemodule.model.*
import com.sinopec.basemodule.utils.ARouterManagerUtils
import com.sinopec.iuhf.IUhfHelper
import com.sinopec.uhf.model.BeeperHelper
import com.sinopec.yelofixedreader.stock.inn.R
import com.sinopec.yelofixedreader.stock.inn.contract.StockInRfidContract
import com.sinopec.yelofixedreader.stock.inn.model.StockInApiRequestModel
import com.sinopec.yelofixedreader.stock.inn.presenter.StockInRfidPresenter
import com.sinopec.yelofixedreader.stock.inn.resultcontract.RFIDIn
import com.sinopec.yelofixedreader.uhf.*
import com.sinopec.yelofixedreader.uhf.dialog.AmountErrorDialog
import com.sinopec.yelofixedreader.uhf.dialog.CodeSameErrorDialog
import com.sinopec.yelofixedreader.uhf.settings.TimeSettings
import com.sinopec.yelofixedreader.uhf.uhfdi.IUHFHelperDi
import com.sinopec.yelofixedreader.uhf.uhfdi.invoke
import kotlinx.android.synthetic.main.activity_stock_in_rfid.*
import kotlinx.android.synthetic.main.activity_stock_in_rfid.ll_back
import kotlinx.android.synthetic.main.activity_stock_in_rfid.tv_device_id
import kotlinx.android.synthetic.main.activity_stock_in_rfid.tv_expectedPalletQuantity
import kotlinx.android.synthetic.main.activity_stock_in_rfid.tv_locationName
import kotlinx.android.synthetic.main.activity_stock_in_rfid.tv_mtrlName
import kotlinx.android.synthetic.main.activity_stock_in_rfid.tv_name
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import kotlin.coroutines.resume

/**
 * @author lwj
 * @ClassName: StockInRfidActivity
 * @Description: 入库-rfid扫码界面
 */
@Route(path = ARouterManagerUtils.GOTO_IN_STOCK_IN_RFID_ACTIVITY)
class StockInRfidActivity : BaseActivityKt<StockInRfidPresenter>(R.layout.activity_stock_in_rfid),
    StockInRfidContract.View {

    private var tipsPopupWindow: TipsPopupWindow? = null
    private val params by lazy { RFIDIn.getParams(this) }

    //读取工作
    var readJob: Job? = null

    //当前第几批
    private var currentBatch: Int = 1
        set(value) {
            field = value
            //每批的数量
            tv_every_count.text = "$currentScanCount"
            //当前第几次
            tv_cur_times.text = "$value"
            //当前应该扫
            tv_plan_count.text = "$currentScanCount"
        }


    //当前应读数量
    private var currentScanCount = 1

    /**
     * 读码器
     */
    private val uhf: IUhfHelper = IUHFHelperDi()(this, IUHFHelperDi.Device.current)

    /**
     * 灯
     */
    private val light by autoCloseLight

    //读码区
    private val rfidLeftAdapter by lazy { ReadCodeAreaAdapter(mContext) }

    //已读有效编码区
    private val rfidRightAdapter by lazy { AlreadyReadAreaAdapter(mContext) }

    private var commonTipsPopupWindow: CommonTipsPopupWindow? = null

    override fun configToolbar(rToolbar: CustomToolbar?) {
        super.configToolbar(rToolbar)
        //配置标题
        rToolbar?.setToolbarVisible(false)
    }

    private fun Flow<String>.readTas(): Job {
        var canRead = true
        return lifecycleScope.launch() {
            val thisJob = this.coroutineContext.job
            this@readTas
                .onStart {
                    tv_stop.text = "暂停"
                }
                .onCompletion {
                    tv_stop.text = "开始"
                    light?.close()
                }
                .filter { it ->
                    val rfidRightList = ArrayList<String>()
                    rfidRightAdapter.datas.forEach {
                        rfidRightList.add(it.code)
                    }

                    //不包含它 才允许添加
                    !rfidLeftAdapter.datas.contains(it) && !rfidRightList.contains(it) && canRead
                    //!rfidLeftAdapter.datas.contains(it) && canRead
                }
                .map {
                    if (it != EmptyTAG) {
                        //每个数据
                        rfidLeftAdapter.datas.add(it)
                        BeeperHelper.beep(R.raw.beeper_short)
                        rfidLeftAdapter?.notifyDataSetChanged()
                    }
                    it
                }
                //这么多时间内不允许提交
                .debounce(TimeSettings.readTime * 1000L)
                .collectLatest {
                    canRead = false
                    //1. 读取到的数量是否和应扫数一致（扫码数大于应扫数报错）
                    checkCount(thisJob)
                    //2、读取到的编码是否与右侧的已读编码存在相同编码，存在就报错
                    //checkCodeSame(thisJob)

                    var isSuccessFlag = true
                    //3. 具体SKU已扫数量是否大于计划出库数（大于报错）
                    val model = StockInApiRequestModel()
                    model.taskRecordId = params?.params?.taskRecordId
                    val palletCode = rfidLeftAdapter.datas[0]
                    model.palletCode = palletCode
                    model.count = currentBatch
                    //提交
                    val commitResult = try {
                        mPresenter?.confirmStockInOrder(model)
                    } catch (e: Exception) {
                        isSuccessFlag = false
                        tipsPopupWindow =
                            TipsPopupWindow.create(mContext, "温馨提示", e.message) {
                            }.setAnchorView(mContext.rootView)
                                .apply()
                        tipsPopupWindow?.showAtLocation(mContext.rootView, Gravity.CENTER, 0, 0)
                        //showMessage(e.message)
                        lifecycleScope.error(light)
                        thisJob.cancelAndJoin()
                        null
                    }


//                    //提交成功
//                    if (commitResult != true) {
//                        isSuccessFlag = false
//                        showMessage("错误编码")
//                        error(light)
//                        thisJob.cancelAndJoin()
//                    } else {
                    // 这里要把正常已提交的编码加入到右边已读区域中去,如果已读取有该编码就不再重复添加
                    val list = ArrayList<PalletCodeStatusModel>()
                    val rfidRightList = ArrayList<String>()
                    rfidRightAdapter.datas.forEach {
                        rfidRightList.add(it.code)
                    }

                    val isHave = rfidRightList.contains(palletCode)
                    if (!isHave) {
                        val palletCodeStatusModel =
                            PalletCodeStatusModel(code = it, state = true)
                        list.add(palletCodeStatusModel)
                    }

                    rfidRightAdapter.datas.addAll(list)
                    rfidRightAdapter.notifyDataSetChanged()
                    tv_actualCount.text = "${rfidRightAdapter.datas.size}"
                    rfidLeftAdapter.datas.clear()
                    rfidLeftAdapter.notifyDataSetChanged()

                    currentBatch++
                    // }

                    if (commitResult?.isFinishOrder == true) {
                        //showMessage("订单已完成！")
                        tipsPopupWindow =
                            TipsPopupWindow.create(mContext, "温馨提示", "订单已完成!") {
                                finish()
                            }.setAnchorView(mContext.rootView)
                                .apply()
                        tipsPopupWindow?.showAtLocation(mContext.rootView, Gravity.CENTER, 0, 0)
                        lifecycleScope.launch {
                            //通过的声音
                            lifecycleScope.warnRing(light)
                        }
                        thisJob.cancelAndJoin()
                    }


                    if (isSuccessFlag) {
                        lifecycleScope.launch {
                            //通过的声音
                            lifecycleScope.success(light)
                        }
                    }

                    //是否叉车模式-叉车模式成功一托就停止
                    if (TimeSettings.isForkliftMode) {
                        thisJob.cancelAndJoin()
                    }

                    //休息时间
                    delay(TimeSettings.divideTime * 1000L)
                    canRead = true
                }
        }
    }

    private suspend fun checkCount(thisJob: Job) {
        val currentReadCount = rfidLeftAdapter.datas.size
        val shouldReadCount = currentScanCount
        //读取到的数量是否和应扫数一致（扫码数大于应扫数报错）
        if (currentReadCount > shouldReadCount) {
            val ringJob = lifecycleScope.errorRing(light)
            val list = ArrayList(rfidLeftAdapter.datas)
            //是否关闭数量不对的弹窗
            val hasCloseCountErrorDialog =
                supportFragmentManager.showCountErrorDialog(
                    shouldReadCount,
                    currentReadCount,
                    list
                )
            if (hasCloseCountErrorDialog) {
                //取消蜂鸣器声音
                ringJob.cancelAndJoin()
            }

            /**
             * lwj at 2023/6/2
             * 清空读码区域
             * 关灯
             */
            rfidLeftAdapter.datas.clear()
            rfidLeftAdapter.notifyDataSetChanged()
            light?.close()

            thisJob.cancelAndJoin()
        }
    }

    /**
     * 刘五军
     * 检查当前扫码批次是否存在相同编码
     */
    private suspend fun checkCodeSame(thisJob: Job) {
        val shouldScanCount = currentScanCount
        val nowScanCount = rfidLeftAdapter.datas.size
        //是否存在相同编码
        var isExistSameCode = false

        val list = ArrayList<PalletCodeStatusModel>()
        //左边扫到编码
        val rfidLeftList = ArrayList(rfidLeftAdapter.datas)
        //右边扫到编码
        val rfidRightList = ArrayList<String>()
        rfidRightAdapter.datas.forEach {
            rfidRightList.add(it.code)
        }
        Log.d("lwj", "checkCodeSame rfidLeftList=$rfidLeftList")
        Log.d("lwj", "checkCodeSame rfidRightList=$rfidRightList")
        rfidLeftList.forEach {
            val isHave = rfidRightList.contains(it)
            val palletCodeStatusModel = PalletCodeStatusModel()
            palletCodeStatusModel.code = it
            if (isHave) {
                //存在相同编码就标记为异常编码false
                palletCodeStatusModel.state = false
                isExistSameCode = true
            } else {
                //正常
                palletCodeStatusModel.state = true
            }
            list.add(palletCodeStatusModel)
        }

        if (isExistSameCode) {
            val ringJob = lifecycleScope.errorRing(light)
            //是否关闭数量不对的弹窗
            val hasCodeSameErrorDialog =
                supportFragmentManager.showCodeSameErrorDialog(
                    shouldScanCount,
                    nowScanCount,
                    list
                )
            if (hasCodeSameErrorDialog) {
                //取消蜂鸣器声音
                ringJob.cancelAndJoin()
            }

            /**
             * lwj at 2023/6/2
             * 清空读码区域
             * 关灯
             */
            rfidLeftAdapter.datas.clear()
            rfidLeftAdapter.notifyDataSetChanged()
            light?.close()

            thisJob.cancelAndJoin()
        }
    }

    override fun initView(savedInstanceState: Bundle?) {
        mPresenter = StockInRfidPresenter(this)

        //任务单号
        tv_taskNo.text = params?.params?.taskNo?.ifEmpty { "--" }
        //仓库名称-库位名称
        tv_locationName.text = params?.params?.locationName?.ifEmpty { "--" }
        //物料名称
        tv_mtrlName.text = params?.params?.mtrlName?.ifEmpty { "--" }
        //预计总重量（吨）
        tv_expectedPalletQuantity.text = params?.params?.expectedPalletQuantity.toString()

        val userInfo = BaseApplication.getInstance().userManager.user
        //设备id
        tv_device_id.text = userInfo.deviceId
        //登录用户
        tv_name.text = userInfo.userAccount

        /*  rfidLeftAdapter = object : CommonAdapter<String>(
              mContext,
              R.layout.item_stock_out_rfid_scanning,
              rfidLeftDatas
          ) {
              override fun convert(
                  holder: CustomViewHolder,
                  s: String,
                  position: Int
              ) {
                  val itemView = holder.itemView
                  //rfid code
                  val tv_rfidCode_left = holder.getView<TextView>(R.id.tv_rfidCode_left)
                  tv_rfidCode_left.text = s
              }
          }*/
        rv_rfid_left.adapter = rfidLeftAdapter

        //已读有效编码区
        /* rfidRightAdapter = object : CommonAdapter<String>(mContext, R.layout.item_stock_out_rfid_valid, rfidRightDatas) {
             override fun convert(
                 holder: CustomViewHolder,
                 s: String,
                 position: Int
             ) {
                 val itemView = holder.itemView
                 //rfid code
                 val tv_rfidCode_right = holder.getView<TextView>(R.id.tv_rfidCode_right)
                 tv_rfidCode_right.text = s
             }
         }*/
        rv_rfid_right.adapter = rfidRightAdapter
    }

    override fun initEvent() {
        super.initEvent()

        /**
         * 退出
         */
        tv_exit.click {
            if (readJob == null || readJob?.isActive == false) {
                finish()
            } else {
                showMessage("正在扫码中，请先停止扫码！")
            }
        }

        ll_back.click {
            if (readJob == null || readJob?.isActive == false) {
                finish()
            } else {
                showMessage("正在扫码中，请先停止扫码！")
            }
        }


        /**
         * 重扫
         */
        tv_restart.click {
            if (readJob == null || readJob?.isActive == false) {
                rfidLeftAdapter.datas.clear()
                rfidLeftAdapter.notifyDataSetChanged()
            } else {
                showMessage("正在扫码中，请先停止扫码！")
            }
        }

        /**
         * 暂停
         */
        tv_stop.click {
            if (readJob?.isActive == true) {
                readJob?.cancel()
            } else {
                readJob = uhf.readStringTags().readTas()
            }
        }

        /**
         * 确认出库完成
         */
        tv_save.click {
            //暂停状态
            if (readJob == null || readJob?.isActive == false) {
                showCommonTipsPopupWindow(R.drawable.icon_reject,
                    "温馨提示",
                    "是否提前完成订单？",
                    "确定",
                    "取消")
            } else {
                showMessage("正在扫码中，请先停止扫码！")
            }
        }
    }

    override fun initData() {
        super.initData()
        currentBatch = 1
    }

    /**
     * @author lwj
     * @Description: 提示弹窗-一个按钮
     */
    private fun showTipsPopupWindow(title: String, content: String) {
        val tipsPopupWindow =
            TipsPopupWindow.create(mContext, title, content) {

            }.setAnchorView(mContext.rootView)
                .apply()
        tipsPopupWindow.showAtLocation(mContext.rootView, Gravity.CENTER, 0, 0)
    }

    /**
     * @author lwj
     * @Description: 提示弹窗两个按钮
     */
    private fun showCommonTipsPopupWindow(
        resId: Int,
        title: String,
        content: String,
        confirmText: String,
        cancelText: String,
    ) {
        commonTipsPopupWindow = CommonTipsPopupWindow.create(mContext,
            resId,
            title,
            content,
            confirmText,
            cancelText, object : CommonTipsPopupWindow.OnSelectListener {
                override fun onConfirm() {
                    params?.params?.taskRecordId?.let { it1 ->
                        mPresenter.confirmStockOutOrderFinish(it1)
                    }
                    commonTipsPopupWindow!!.dismiss()
                }

                override fun onCancel() {
                    commonTipsPopupWindow!!.dismiss()
                }
            }).setAnchorView(mContext.rootView)
            .apply()
        commonTipsPopupWindow?.showAtLocation(mContext.rootView, Gravity.CENTER, 0, 0)
    }

    override fun onKeyUp(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_A) {
            //showMessage("抬起：字母A")
            //是否叉车模式-叉车模式成功一托就停止
            if (TimeSettings.isForkliftMode) {
                if (readJob?.isActive == true) {
                    readJob?.cancel()
                } else {
                    readJob = uhf.readStringTags().readTas()
                }
            }
            return true
        }
        return super.onKeyUp(keyCode, event)
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        if (keyCode == KeyEvent.KEYCODE_A) {
            //showMessage("按下：字母A")
            return true
        }
        return super.onKeyDown(keyCode, event)
    }
}


/**
 * lwj at 2023/6/1
 * 显示扫码数量错误弹窗提示
 */
private suspend fun FragmentManager.showCountErrorDialog(
    shouldScanCount: Int,
    nowScanCount: Int,
    list: ArrayList<String>,
): Boolean {
    return suspendCancellableCoroutine { continuation ->
        AmountErrorDialog(
            shouldScanCount.toString(),
            nowScanCount.toString(),
            list
        ) {
            continuation.resume(true)
        }.show(this, "")
    }
}

/**
 * @author lwj
 * @ClassName: CodeSameErrorDialog
 * @Description: 整个批次内编码存在重复
 */
private suspend fun FragmentManager.showCodeSameErrorDialog(
    shouldScanCount: Int,
    nowScanCount: Int,
    list: ArrayList<PalletCodeStatusModel>,
): Boolean {
    return suspendCancellableCoroutine { continuation ->
        CodeSameErrorDialog(
            shouldScanCount.toString(),
            nowScanCount.toString(),
            list
        ) {
            continuation.resume(true)
        }.show(this, "")
    }
}

